<template>
  <div class="file-list-container">
    <h2>文件列表</h2>
    <div class="filter-container" v-if="!props.files">
      <label for="departmentFilter">按科室筛选：</label>
      <select id="departmentFilter" v-model="selectedDepartment">
        <option value="null">全部文件</option>
        <option v-for="dept in departments" :key="dept.id" :value="dept.id">{{ dept.name }}</option>
      </select>
    </div>

    <div class="file-table-container">
      <table class="file-table">
        <thead>
          <tr>
            <th>文件名</th>
            <th>类型</th>
            <th>大小</th>
            <th>上传时间</th>
            <th>所属科室</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
            <!-- 显示独立文件 -->
            <template v-if="filesByFolder.independentFiles.length > 0">
              <tr v-for="file in filesByFolder.independentFiles" :key="file.id" class="file-row">
                <td class="file-name val_nowrap">
                  <span :class="{'file-icon': true, 'word-icon': file.type?.includes('word'), 'pdf-icon': file.type === 'pdf', 'excel-icon': file.type?.includes('excel'), 'ppt-icon': file.type?.includes('powerpoint'), 'image-icon': file.type && ['jpeg', 'png', 'gif'].includes(file.type)}"></span>
                  {{ file.name || '未命名文件' }}
                </td>
                <td class="val_nowrap val_align">{{ getFileTypeDisplay(file.type, file.name) }}</td>
                <td class="val_nowrap val_align">{{ formatFileSize(file.size) }}</td>
                <td class="val_nowrap val_align">{{ file.uploadTime }}</td>
                <td class="val_nowrap val_align">{{ getDepartmentName(file.department_id) }}</td>
                <td class="action-buttons val_nowrap val_align">
                  <button class="download-btn" @click="handleDownload(file)">下载</button>
                  <button class="delete-btn" @click="handleDelete(file.id)">删除</button>
                </td>
              </tr>
            </template>

          <!-- 遍历文件夹 -->
          <template v-for="(folderFiles, folderName) in filesByFolder.folders" :key="folderName">
            <tr class="folder-row">
              <td class="folder-name val_nowrap" colspan="6">
                <button
                  class="folder-toggle-btn"
                  @click="toggleFolder(folderName)"
                >
                  {{ expandedFolders[folderName] ? '▼' : '▶' }}
                </button>
                <span class="folder-icon"></span>
                {{ folderName }} ({{ folderFiles.length }} 个文件)
              </td>
            </tr>

            <!-- 显示文件夹内的文件（如果展开） -->
            <template v-if="expandedFolders[folderName]">
              <tr v-for="file in folderFiles" :key="file.id" class="file-row">
                <td class="file-name val_nowrap folder-file">
                  <span :class="{'file-icon': true, 'word-icon': file.type?.includes('word'), 'pdf-icon': file.type === 'pdf', 'excel-icon': file.type?.includes('excel'), 'ppt-icon': file.type?.includes('powerpoint'), 'image-icon': file.type && ['jpeg', 'png', 'gif'].includes(file.type)}"></span>
                  {{ file.name || '未命名文件' }}
                </td>
                <td class="val_nowrap val_align">
                  {{ getFileTypeDisplay(file.type, file.name) }}
                </td>
                <td class="val_nowrap val_align">{{ formatFileSize(file.size) }}</td>
                <td class="val_nowrap val_align">{{ file.uploadTime }}</td>
                <td class="val_nowrap val_align">{{ getDepartmentName(file.department_id) }}</td>
                <td class="action-buttons val_nowrap val_align">
                  <button class="download-btn" @click="handleDownload(file)">下载</button>
                  <button class="delete-btn" @click="handleDelete(file.id)">删除</button>
                </td>
              </tr>
            </template>
          </template>

          <!-- 当没有文件时显示 -->
          <tr v-if="filesByFolder.independentFiles.length === 0 && Object.keys(filesByFolder.folders).length === 0">
            <td colspan="6" class="no-data">暂无文件数据</td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 分页控件 -->
    <div class="pagination-container val_nowrap" >
      <!-- <div class="pagination-debug" style="margin-top: 10px; color: #666; font-size: 12px;">
        【分页调试】当前页: {{ currentPage }} / {{ totalPages }}, 每页条数: {{ pageSize }}, 总条数: {{ totalItems }}
      </div> -->
      <div class="pagination-info">
        总共 {{ totalItems }} 条记录，共 {{ totalPages }} 页
        <!-- <span style="margin-left: 10px; color: #999; font-size: 12px;">调试: currentPage={{ currentPage }}, totalItems={{ totalItems }}, pageSize={{ pageSize }}</span> -->
      </div>
      <div class="pagination-buttons">
        <button :disabled="currentPage === 1" @click="currentPage = 1">首页</button>
        <button :disabled="currentPage === 1" @click="currentPage--">上一页</button>
        <span v-for="page in visiblePages" :key="page" :class="{ 'active-page': page === currentPage }"
              @click="currentPage = page">{{ page }}</span>
        <button :disabled="currentPage === totalPages" @click="currentPage++">下一页</button>
        <button :disabled="currentPage === totalPages" @click="currentPage = totalPages">末页</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch } from 'vue';

// 组件挂载时执行
onMounted(() => {
  // console.log('FileList组件已挂载');
  fetchDepartments();
  
  // 触发filteredFiles计算，确保totalItems被正确初始化
  // console.log('【分页调试】初始触发filteredFiles计算');
  filteredFiles.value;
  
  // 如果没有传入files属性，则获取文件数据
  if (!props.files) {
    fetchFiles();
  }
});
import { getDepartments, getFiles, deleteFile, downloadFile } from '@/services/api';

// 添加全局错误处理
import axios from 'axios';

// 添加请求拦截器以记录请求信息
axios.interceptors.request.use(config => {
  // console.log('发送请求:', config.url);
  return config;
}, error => {
  // console.error('请求拦截器错误:', error);
  return Promise.reject(error);
});

// 添加响应拦截器以处理错误
axios.interceptors.response.use(
  response => {
    // console.log('请求成功:', response.config.url, '状态码:', response.status);
    return response;
  },
  error => {
    // console.error('API请求错误:', error);
    return Promise.reject(error);
  }
);

// 定义props
const props = defineProps({
  files: {
    type: Array,
    default: null
  }
});

// 响应式数据
const selectedDepartment = ref('null'); // 初始化为字符串'null'，与模板选项值匹配
const localFiles = ref([]);
const departments = ref([]);
const loading = ref(false);
const departmentsLoading = ref(false);
const departmentsError = ref(null);
// 文件夹展开状态管理
const expandedFolders = ref({});

// 分页相关数据
const currentPage = ref(1);
const pageSize = ref(6); // 默认每页6条
const totalItems = ref(0);
const totalPages = computed(() => Math.ceil(totalItems.value / pageSize.value));

// 监听页码变化，重新获取文件
watch(currentPage, () => {
  if (!props.files) {
    fetchFiles();
  }
});

// 监听每页条数变化，重置到第一页并重新获取文件
watch(pageSize, () => {
  if (!props.files) {
    currentPage.value = 1;
    fetchFiles();
  }
});

// 计算可见页码范围
const visiblePages = computed(() => {
  // console.log('【分页调试】计算visiblePages - currentPage:', currentPage.value, 'totalPages:', totalPages.value);
  const maxVisible = 5; // 最多显示5个页码
  let startPage = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
  let endPage = Math.min(totalPages.value, startPage + maxVisible - 1);

  // 调整起始页码，确保显示足够的页码
  if (endPage - startPage + 1 < maxVisible && startPage > 1) {
    startPage = Math.max(1, endPage - maxVisible + 1);
  }

  // 确保至少显示1个页码
  if (startPage > endPage) {
    startPage = 1;
    endPage = Math.min(maxVisible, totalPages.value);
  }

  const pages = Array.from({ length: endPage - startPage + 1 }, (_, i) => startPage + i);
  // console.log('【分页调试】visiblePages:', pages);
  return pages;
});

// 分离文件夹和独立文件（基于分页后的数据）
const filesByFolder = computed(() => {
  const filesToGroup = paginatedFiles.value;
  const result = {
    folders: {},
    independentFiles: []
  };
  
  filesToGroup.forEach(file => {
    if (file.folder_name) {
      // 有folder_name的文件归入对应文件夹
      if (!result.folders[file.folder_name]) {
        result.folders[file.folder_name] = [];
      }
      result.folders[file.folder_name].push(file);
    } else {
      // 没有folder_name的文件作为独立文件
      result.independentFiles.push(file);
    }
  });
  
  return result;
});

// 计算当前页显示的文件
const paginatedFiles = computed(() => {
  const filesToPaginate = props.files || filteredFiles.value;
  const startIndex = (currentPage.value - 1) * pageSize.value;
  const endIndex = startIndex + pageSize.value;
  return filesToPaginate.slice(startIndex, endIndex);
});

// 获取部门数据
const fetchDepartments = async () => {
  console.log('【部门数据】开始获取部门数据');
  departmentsLoading.value = true;
  departmentsError.value = null;
  try {
    // console.log('【部门数据】发送请求到API');
    const response = await getDepartments();
    // console.log('【部门数据】请求返回，状态码:', response.status);
    // console.log('【部门数据】获取成功，原始数据:', response.data);
    
    // 确保response.data是数组
    if (Array.isArray(response.data)) {
      departments.value = response.data;
      // console.log('【部门数据】更新完成，共', departments.value.length, '个部门');
      // console.log('【部门数据】部门列表:', departments.value);
    } else if (response.data && response.data.departments) {
      // 如果数据嵌套在departments字段中
      departments.value = response.data.departments;
      // console.log('【部门数据】从departments字段更新，共', departments.value.length, '个部门');
    } else {
      // console.error('【部门数据】数据格式不正确，不是数组:', response.data);
      departmentsError.value = '部门数据格式不正确';
    }
  } catch (error) {
    // console.error('【部门数据】获取失败:', error.message);
    departmentsError.value = '获取部门数据失败: ' + error.message;
  } finally {
    departmentsLoading.value = false;
    // console.log('【部门数据】加载状态更新为:', departmentsLoading.value);
  }
};

// 计算属性
const filteredFiles = computed(() => {
  // 如果传入了files属性，则使用传入的文件
  if (props.files) {
    // 更新totalItems以反映传入文件的总数
    const filesCount = Array.isArray(props.files) ? props.files.length : 0;
    // console.log('【分页调试】通过props传入的文件数量:', filesCount);
    totalItems.value = filesCount;
    return Array.isArray(props.files) ? props.files : [];
  }
  // 否则使用本地文件并应用科室过滤
  const deptId = selectedDepartment.value === 'null' ? null : parseInt(selectedDepartment.value);
  const filtered = localFiles.value.filter(file => !deptId || file.department_id === deptId);
  // 更新totalItems以反映过滤后的文件总数
  // console.log('【分页调试】过滤后的文件数量:', filtered.length);
  totalItems.value = filtered.length;
  return filtered;
});

// 监听props.files变化，确保totalItems及时更新
watch(() => props.files, (newFiles) => {
  // console.log('【分页调试】props.files发生变化:', newFiles);
  // 触发filteredFiles重新计算
  filteredFiles.value;
}, { deep: true });

// 获取部门名称
const getDepartmentName = (id) => {
    // 处理null、undefined或空字符串的情况
    if (id === null || id === undefined || id === '') {
      // console.log('部门ID为空');
      return '无科室';
    }
    
    // 确保id是数字类型
    const numId = Number(id);
    
    // 检查id是否有效
    if (isNaN(numId)) {
      // console.log('无效的部门ID:', id);
      return '无科室';
    }
    
    // 检查部门数据是否正在加载
    if (departmentsLoading.value) {
      // console.log('部门数据正在加载中...');
      return '加载中...';
    }
    
    // 检查部门数据是否已加载
    if (!departments.value || departments.value.length === 0) {
      // console.log('部门数据尚未加载');
      return '未加载';
    }
    
    // 查找对应的部门
    const dept = departments.value.find(dept => dept.id === numId);
    
    // 如果找不到部门，记录日志
    if (!dept) {
      // console.log('未找到对应的部门，ID:', numId);
      return '未知科室';
    }
    
    return dept.name;
  };

// 获取文件数据 - 修复重复声明问题
const fetchFiles = async () => {
  // console.log('【文件数据】开始获取文件数据');
  // console.log('【分页调试】currentPage:', currentPage.value, 'pageSize:', pageSize.value);
  loading.value = true;
  try {
    // 根据选择的科室筛选文件
    const deptId = selectedDepartment.value === 'null' ? null : parseInt(selectedDepartment.value);
    const params = {
      ...(deptId ? { department_id: deptId } : {}),
      page: currentPage.value,
      page_size: pageSize.value
    };
    // console.log('【文件数据】请求参数:', params);
    
    const response = await getFiles(params);
    // console.log('【文件数据】响应数据:', response.data);
    // console.log('【文件数据】请求返回，状态码:', response.status);
    // console.log('【文件数据】响应头:', response.headers);
    // console.log('【文件数据】获取成功，原始数据:', response.data);
    
    // 查找类型为undefined的文件
    if (Array.isArray(response.data)) {
      const undefinedTypeFiles = response.data.filter(file => file.type === undefined || file.type === null || file.type === '');
      if (undefinedTypeFiles.length > 0) {
        // console.log(`【文件数据警告】发现${undefinedTypeFiles.length}个文件类型为undefined/null/空字符串:`);
        undefinedTypeFiles.forEach(file => {
          // console.log(`  - ${file.name || '未命名文件'} (ID: ${file.id})`);
        });
      }
    } else if (response.data && response.data.files) {
      const undefinedTypeFiles = response.data.files.filter(file => file.type === undefined || file.type === null || file.type === '');
      if (undefinedTypeFiles.length > 0) {
        // console.log(`【文件数据警告】发现${undefinedTypeFiles.length}个文件类型为undefined/null/空字符串:`);
        undefinedTypeFiles.forEach(file => {
          // console.log(`  - ${file.name || '未命名文件'} (ID: ${file.id})`);
        });
      }
    }
    
    // 确保response.data是数组或包含files数组
    if (Array.isArray(response.data)) {
      localFiles.value = response.data;
      totalItems.value = response.data.length;
      // console.log('【文件数据】更新完成，共', localFiles.value.length, '个文件');
      // console.log('【分页调试】设置totalItems:', totalItems.value);
    } else if (response.data && response.data.files) {
      // 如果数据嵌套在files字段中
      localFiles.value = Array.isArray(response.data.files) ? response.data.files : [];
      const filesCount = Array.isArray(response.data.files) ? response.data.files.length : 0;
      totalItems.value = response.data.total !== undefined && typeof response.data.total === 'number' ? response.data.total : filesCount;
      // console.log('【文件数据】从files字段更新，共', filesCount, '个文件');
      // console.log('【文件数据】总文件数:', totalItems.value);
      // console.log('【分页调试】设置totalItems:', totalItems.value);
    } else {
      // console.error('【文件数据】数据格式不正确:', response.data);
      localFiles.value = [];
      totalItems.value = 0;
      // console.log('【分页调试】设置totalItems:', totalItems.value);
    }
    
    // 打印文件数据详情，便于调试类型和部门ID问题
    if (localFiles.value.length > 0) {
      // console.log('【文件数据】共', localFiles.value.length, '个文件');
      
      // 打印所有文件的类型信息
      localFiles.value.forEach((file, index) => {
        // console.log(`【文件数据】文件${index + 1}详情:`, file);
        // console.log(`【文件数据】文件${index + 1}类型:`, file.type, '类型:', typeof file.type);
        
        // 特别标记类型为undefined的文件
        if (file.type === undefined || file.type === null || file.type === '') {
          // console.warn(`【文件数据警告】文件${index + 1}(${file.name})类型为空:`, file.type);
        }
      });
    } else {
      // console.log('【文件数据】未获取到任何文件');
    }
  } catch (error) {
    // console.error('【文件数据】获取失败:', error.message);
    localFiles.value = [];
  } finally {
    loading.value = false;
    // console.log('【文件数据】加载状态更新为:', loading.value);
  }
};

// 监听科室选择变化，重新获取文件
watch(selectedDepartment, () => {
  if (!props.files) {
    // console.log('【文件数据】科室选择变化，重新获取文件');
    fetchFiles();
  }
});

// 获取文件类型显示
// 添加fileName参数用于更详细的调试
const getFileTypeDisplay = (type, fileName = '未知文件名') => {
  // 打印原始类型值和文件名，便于调试
  // console.log('【文件类型调试】文件:', fileName, '原始类型值:', type, '类型:', typeof type);

  // 处理null或undefined的情况
  if (type === null || type === undefined || type === '') {
    // console.log('【文件类型调试】文件:', fileName, '类型为null或undefined');
    return '未知类型';
  }

  // 确保type是字符串
  const typeStr = String(type);
  // console.log('【文件类型调试】转换为字符串后的类型:', typeStr);

  // 标准化类型字符串（转为小写并移除可能的前缀）
  let normalizedType = typeStr.toLowerCase();
  // console.log('【文件类型调试】标准化前的类型:', typeStr, '-> 标准化后的类型:', normalizedType);

  // 移除所有常见的MIME类型前缀
  const mimePrefixes = ['application/', 'image/', 'video/', 'audio/', 'text/', 'multipart/'];
  for (const prefix of mimePrefixes) {
    if (normalizedType.startsWith(prefix)) {
      // console.log(`【文件类型调试】检测到前缀${prefix}，准备移除`);
      normalizedType = normalizedType.replace(prefix, '');
      // console.log(`【文件类型调试】移除${prefix}前缀后:`, normalizedType);
      break;
    }
  }


    // console.log('【文件类型调试】检测到msword相关类型:', normalizedType);

  // 扩展类型映射表
  const typeMap = {
    'pdf': 'PDF文档',
    'msword': 'Word文档',
    'application/msword': 'Word文档',
    'vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word文档',
    'vnd.ms-excel': 'Excel文档',
    'vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel文档',
    'vnd.ms-powerpoint': 'PowerPoint文档',
    'vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint文档',
    'jpeg': '图片',
    'jpg': '图片',
    'png': '图片',
    'gif': '图片',
    'bmp': '图片',
    'tiff': '图片',
    'webp': '图片',
    'svg+xml': 'SVG图片',
    'mp4': '视频',
    'avi': '视频',
    'mov': '视频',
    'wmv': '视频',
    'flv': '视频',
    'mp3': '音频',
    'wav': '音频',
    'ogg': '音频',
    'm4a': '音频',
    'zip': '压缩文件',
    'rar': '压缩文件',
    '7z': '压缩文件',
    'tar': '压缩文件',
    'gz': '压缩文件',
    'txt': '文本文件',
    'csv': 'CSV文件',
    'json': 'JSON文件',
    'html': 'HTML文件',
    'css': 'CSS文件',
    'javascript': 'JavaScript文件',
    'xml': 'XML文件',
    'doc': 'Word文档',
    'docx': 'Word文档',
    'xls': 'Excel文档',
    'xlsx': 'Excel文档',
    'ppt': 'PowerPoint文档',
    'pptx': 'PowerPoint文档'
  };

  // 先尝试精确匹配
  // console.log('【文件类型调试】尝试精确匹配 - normalizedType:', normalizedType);
  // console.log('【文件类型调试】typeMap中是否存在msword:', typeMap['msword']);
  // console.log('【文件类型调试】当前normalizedType是否等于msword:', normalizedType === 'msword');

  if (typeMap[normalizedType]) {
    // console.log('【文件类型调试】文件类型匹配成功:', normalizedType, '->', typeMap[normalizedType]);
    return typeMap[normalizedType];
  } else if (normalizedType.includes('msword')) {
    // console.log('【文件类型调试】检测到包含msword但未精确匹配:', normalizedType);
    return 'Word文档';
  }

  // 尝试使用文件扩展名进行匹配（如果类型中包含'.'）
  if (normalizedType.includes('.')) {
    const extension = normalizedType.split('.').pop();
    if (typeMap[extension]) {
      // console.log('【文件类型调试】文件扩展名匹配成功:', extension, '->', typeMap[extension]);
      return typeMap[extension];
    }
  }

  // 增强的模糊匹配逻辑
  const fuzzyMatches = [
    { keywords: ['word', 'doc'], result: 'Word文档' },
    { keywords: ['excel', 'xls'], result: 'Excel文档' },
    { keywords: ['powerpoint', 'ppt', 'presentation'], result: 'PowerPoint文档' },
    { keywords: ['image', 'img', 'picture', 'photo'], result: '图片' },
    { keywords: ['video', 'movie', 'film'], result: '视频' },
    { keywords: ['audio', 'sound', 'music'], result: '音频' },
    { keywords: ['text', 'txt'], result: '文本文件' },
    { keywords: ['compressed', 'archive', 'zip', 'rar', '7z', 'tar', 'gz'], result: '压缩文件' },
    { keywords: ['code', 'script', 'javascript', 'python', 'java', 'c++', 'c#'], result: '代码文件' },
    { keywords: ['html', 'css', 'xml', 'json', 'csv'], result: '网页/数据文件' }
  ];

  for (const { keywords, result } of fuzzyMatches) {
    if (keywords.some(keyword => normalizedType.includes(keyword))) {
      // console.log('【文件类型调试】模糊匹配成功:', normalizedType, '->', result);
      return result;
    }
  }

  // 记录未识别的类型，便于后续完善
  // console.log('【文件类型调试】未识别的文件类型:', type, '->', normalizedType);
  return normalizedType || '未知类型';
}
  

// 已删除重复的onMounted钩子函数

// 已删除重复的fetchFiles函数声明

// 已删除重复的watch监听函数

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

// 切换文件夹展开状态
const toggleFolder = (folderName) => {
  expandedFolders.value = {
    ...expandedFolders.value,
    [folderName]: !expandedFolders.value[folderName]
  };
};

// 下载文件
const handleDownload = async (file) => {
  try {
    // console.log('开始下载文件:', file.id, file.name);
    const response = await downloadFile(file.id);
    
    // console.log('下载响应状态:', response.status);
    // console.log('响应头:', response.headers);
    
    // 创建下载链接
    const url = URL.createObjectURL(new Blob([response.data]));
    const a = document.createElement('a');
    a.href = url;
    a.download = file.name;
    
    // 触发下载
    document.body.appendChild(a);
    a.click();
    
    // 确保元素存在再移除，避免parentNode错误
    setTimeout(() => {
      if (a.parentNode === document.body) {
        document.body.removeChild(a);
      }
      URL.revokeObjectURL(url);
    }, 0);
  } catch (error) {
    // console.error('下载文件失败:', error);
    // console.error('错误代码:', error.code);
    // console.error('错误配置:', error.config);
    // console.error('错误请求:', error.request);
    alert(`下载文件失败: ${error.message || '网络错误'}`);
  }
};

// 删除文件
const handleDelete = async (id) => {
  if (confirm('确定要删除这个文件吗？')) {
    try {
      // console.log('尝试删除文件，ID:', id);
      const response = await deleteFile(id);
      // console.log('删除文件成功，响应:', response);
      
      // 立即从本地数据中移除删除的文件，提升用户体验
if (!props.files) {
  // 方法1: 使用filter创建新数组
  const updatedFiles = localFiles.value.filter(file => file.id !== id);
  // 简化更新逻辑，直接赋值新数组
  localFiles.value = [...updatedFiles];
  // console.log('本地文件列表已更新，移除文件ID:', id);
} else {
  // 如果是从父组件传入的files，发出事件通知父组件更新
  emit('fileDeleted', id);
}
      
      // 延迟调用fetchFiles，确保UI先更新
      setTimeout(() => {
        fetchFiles();
      }, 300);
    } catch (error) {
      // console.error('删除文件失败:', error);
      // console.error('错误详情:', error.response || error.message);
      alert(`删除文件失败: ${error.response?.data?.message || error.message}`);
    }
  }
};

// 定义emit事件
const emit = defineEmits(['fileDeleted', 'filesUpdated']);
</script>

<style scoped>
.file-list-container {
  max-width: 100vw;
  min-height: 72vh; /* 限制容器高度最少为视口高度的70% */
  overflow-y: auto; /* 添加垂直滚动 */
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  position: relative;
}

h2 {
  text-align: center;
  color: #333;
  margin-bottom: 20px;
}

.filter-container {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.filter-container label {
  font-weight: 500;
  color: #555;
}

.filter-container select {
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.file-table-container {
  overflow-x: auto;
}

.file-table {
  width: 100%;
  border-collapse: collapse;
  background-color: white;
}

.file-table th,
.file-table td {
  padding: 12px 15px;
  text-align: center;
  
}

.file-table th {
  background-color: #f2f2f2;
  font-weight: 600;
  color: #333;
}

.file-row {
  border-bottom: 1px solid rgb(226, 221, 221);
}

.file-row:hover {
  background-color: #f8f8f8;
}

.file-name {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 25px 15px !important;
  max-width: 400px;
}

.val_nowrap {
  text-overflow: ellipsis;
  overflow: hidden;
  -webkit-line-clamp: 1;
  text-align: left !important;
}

.val_align {
  text-align: center !important;
}

.pagination-container {
  margin: 0 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  position:absolute;
  bottom: 5px;
  width: -webkit-fill-available
}

.pagination-info {
  color: #666;
  font-size: 14px;
  margin: auto;
}

.pagination-buttons {
  display: flex;
  gap: 5px;
}

.pagination-buttons button {
  padding: 5px 10px;
  background-color: #f0f0f0;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
}

.pagination-buttons button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.pagination-buttons button:hover:not(:disabled) {
  background-color: #e0e0e0;
}

.pagination-buttons span {
  padding: 5px 10px;
  cursor: pointer;
  border-radius: 4px;
}

.active-page {
  background-color: #1890ff;
  color: white;
  font-weight: bold;
}

.file-icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  border-radius: 3px;
}

.folder-icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: #ffc107;
  border-radius: 3px 3px 0 0;
  position: relative;
  margin-right: 8px;
}

.folder-icon::after {
  content: '';
  position: absolute;
  bottom: -5px;
  left: 0;
  width: 28px;
  height: 15px;
  background-color: #ffc107;
  border-radius: 0 3px 3px 3px;
  z-index: -1;
}

.folder-toggle-btn {
  background: none;
  border: none;
  font-size: 16px;
  cursor: pointer;
  padding: 0 5px;
  color: #666;
}

.folder-row {
  background-color: whitesmoke;
  font-weight: 600;
}

.folder-name {
  text-align: left !important;
  align-items: left;
  gap: 8px;
  padding: 25px 15px !important;
}

.folder-file {
  padding-left: 30px !important;
}

.word-icon {
  background-color: #2b579a;
}

.pdf-icon {
  background-color: #e14b31;
}

.action-buttons {
  display: flex;
  gap: 5px;
}

.delete-btn {
  padding: 5px 10px;
  background-color: #ff4d4f;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.delete-btn:hover {
  background-color: #ff7875;
}

.download-btn {
  padding: 5px 10px;
  background-color: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.download-btn:hover {
  background-color: #40a9ff;
}

.no-data {
  text-align: center;
  color: #999;
  font-style: italic;
}
</style>